/* Orbas:
 *     A open source CORBA Specification implementation from Huihoo.
 *
 * Copyright 2002-2003 Huihoo.org, Inc. All Right Reserved.
 *
 * This software is licensed under LGPL license.
 * See terms of license at gnu.org.
 *
 * For more information, visit:
 *
 * http://www.huihoo.org/orbas
 */

package org.huihoo.orbas.util;

/**
 * <p>Description: This class is used to log information.</p>
 * <p>Copyright (c) 2003</p>
 * <p>Company: <a href="http://www.huihoo.org/orbas">huihoo.org</a></p>
 * @author <a href="http://www.huihoo.org/~cocia">Cocia Lin(cocia@163.com)</a>
 * @see <a href="http://www.huihoo.org/orbas">http://www.huihoo.org/orbas</a>
 * @version 1.0
 */

import java.util.LinkedList;
import java.util.List;

public class CommonLogger implements Logger {

	private String name;
	private Thread msgThread;
	private final List msgQuene = new LinkedList();
	private final Object lock = new Object();

	/**
	 * If name is a null string, we will use root logger.
	 * 
	 * @param name
	 *            String, logger name
	 */
	public CommonLogger(String name) {
		this.name = name;
		//
		msgThread = new Thread() {
			public void run() {
				while (true) {
					synchronized (msgQuene) {

						while (msgQuene.size() != 0) {
							MsgNode node = (MsgNode) msgQuene.remove(0);
							System.out.println(node.msg);
							if (node.t != null) {
								node.t.printStackTrace(System.out);
							}
						}
						// wait for msgQuene data.
						try {
							msgQuene.wait();
						} catch (InterruptedException e) {
						}

					}
				}

			}
		};
		msgThread.setDaemon(true);
		msgThread.start();

	}

	/**
	 * Log debug info.
	 * 
	 * @param msg
	 *            Ojbect
	 * @param t
	 *            Throwable
	 */
	public void debug(Object msg, Throwable t) {
		synchronized (msgQuene) {
			msgQuene.add(new MsgNode("[Debug-" + name + "] " + msg.toString(),
					t));
			msgQuene.notifyAll();
		}
	}

	public void debug(Object msg) {
		debug(msg, null);
	}

	/**
	 * Log general info.
	 * 
	 * @param msg
	 *            Ojbect
	 * @param t
	 *            Throwable
	 */
	public void info(Object msg, Throwable t) {
		synchronized (msgQuene) {
			msgQuene.add(new MsgNode("[Info-" + name + "] " + msg.toString(), t));
			// msgThread.notify();
			msgQuene.notifyAll();
		}
	}

	public void info(Object msg) {
		info(msg, null);
	}

	/**
	 * Log warnning info.
	 * 
	 * @param msg
	 *            Ojbect
	 * @param t
	 *            Throwable
	 */
	public void warn(Object msg, Throwable t) {
		synchronized (msgQuene) {
			msgQuene.add(new MsgNode("[Warn-" + name + "] " + msg.toString(), t));
			msgQuene.notifyAll();
		}
	}

	public void warn(Object msg) {
		warn(msg, null);
	}

	/**
	 * Log error info.
	 * 
	 * @param msg
	 *            Ojbect
	 * @param t
	 *            Throwable
	 */
	public void error(Object msg, Throwable t) {
		synchronized (msgQuene) {
			msgQuene.add(new MsgNode("[Error-" + name + "] " + msg.toString(),
					t));
			msgQuene.notifyAll();
		}
	}

	public void error(Object msg) {
		error(msg, null);
	}

	/**
	 * Log fatal error info.
	 * 
	 * @param msg
	 *            Ojbect
	 * @param t
	 *            Throwable
	 */
	public void fatal(Object msg, Throwable t) {
		synchronized (msgQuene) {
			msgQuene.add(new MsgNode("[Fatal-" + name + "] " + msg.toString(),
					t));
			msgQuene.notifyAll();
		}
	}

	public void fatal(Object msg) {
		error(msg, null);
	}

	private class MsgNode {
		public MsgNode(Object msg, Throwable t) {
			this.msg = msg;
			this.t = t;
		}

		public Object msg;
		public Throwable t;
	}

}
